package org.stvd.repository.admin.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Repository;
import org.stvd.entities.admin.Menus;
import org.stvd.repository.admin.MenusDao;
import org.stvd.repository.base.impl.BaseDaoImpl;

@Repository("MenusDao")
public class MenusDaoImpl extends BaseDaoImpl<Menus> implements MenusDao {

    @Override
    public List<Menus> findAll(String guid) {
        return findByHQL("from Menus T where T.guid = ?0 order by T.orderNo asc", guid);
    }

    @Override
    public List<Menus> findByParentID(String guid, String upperId) {
        return findByHQL("from Menus T where T.guid = ?0 and T.upperId = ?1 order by T.orderNo ", guid, upperId);
    }

    @Override
    public List<Menus> findByUid(String userId, String guid) {
        String hql = " SELECT DISTINCT T1 FROM Menus T1 WHERE T1.type = '1' OR"
            + " (T1.menuId IN (SELECT T3.menuId FROM RoleMenu T3 WHERE T3.roleId IN ("
                + " SELECT T2.roleId FROM UserRole T2 WHERE T2.userId = ?0 AND T2.guid = ?1)"
            + " )) ORDER BY T1.orderNo";
        return  findByHQL(hql, userId, guid);
    }

    @Override
    public List<Menus> findByRid(List<String> roleIds, String guid){
        String hql = "SELECT DISTINCT T1 FROM Menus T1, RoleMenu T2 "
            + " WHERE (T1.menuId = T2.menuId AND T2.roleId IN (?0) AND T2.guid = ?1) OR T1.type = '1'"
            + " ORDER BY T1.orderNo ";
        return findByHQL(hql, roleIds, guid);
    }
    
    @Override
    public List<Menus> getAllMenusByParentID(String guid, String upperId) {
        List<Menus> list = new ArrayList<Menus>();
        List<Menus> lsTmp = findByParentID(guid, upperId);
        list.addAll(lsTmp);
        for (Menus menu : lsTmp) {
            list.addAll(getAllMenusByParentID(guid, menu.getMenuId()));
        }
        return list;
    }
    
    @Override
    public void insertMenu(Menus menus) {
        em.persist(menus);
        if (!menus.getUpperId().equals("-1")) {
            em.flush();
            updateMenuState(menus.getGuid(), menus.getUpperId());
        }
    }

    @Override
    public void updateMenu(Menus menus, String upperId) {
        if (!findByParentID(menus.getGuid(), menus.getMenuId()).isEmpty()) {
            menus.setState("closed");
        }
        em.merge(menus);
        if (!menus.getUpperId().equals(upperId)) {
            em.flush();
            if (!menus.getUpperId().equals("-1")) {
                updateMenuState(menus.getGuid(), menus.getUpperId());
            }
            if (!"-1".equals(upperId)) {
                updateMenuState(menus.getGuid(), upperId);
            }
        }
    }

    @Override
    public void updateMenuState(String guid, String upperId) {
        if (!findByParentID(guid, upperId).isEmpty()) {
            em.createQuery("update Menus set state='closed' where (guid = :guid OR guid = '') and menuId = :menuId")
                .setParameter("guid", guid).setParameter("menuId", upperId).executeUpdate();
        } else {
            em.createQuery("update Menus set state='open' where (guid = :guid OR guid = '') and menuId = :menuId")
                .setParameter("guid", guid).setParameter("menuId", upperId).executeUpdate();
        }
    }

    @Override
    public void deleteMenu(Menus menus) {
        em.remove(em.find(Menus.class, menus.getMenuId()));
        if (!menus.getUpperId().equals("-1")) {
            em.flush();
            updateMenuState(menus.getGuid(), menus.getUpperId());
        }
    }
}
